#include "dbusservice.h"
#include "dbusmplayercli.h"
#include <QDBusConnection>
#include <QtDBus>
#include <QDBusInterface>
#include <QDBusConnectionInterface>
#include <QMetaObject>
#include <QDBusReply>

DbusService::DbusService()
{
    QDBusConnectionInterface * interf = QDBusConnection::sessionBus().interface();
    QObject::connect(interf,SIGNAL(serviceOwnerChanged(QString,QString,QString)),this,SLOT(serviceOwnerChanged(QString,QString,QString)));
    init=false;
    qDebug()<< "init DbusService ";
}


void DbusService::setService(const QString & service){
    //qDebug()<< "ser OK";
    m_service=service;
}

void DbusService::setPath(const QString & path){
    //qDebug()<< "path OK";
    m_path=path;
}
void DbusService::setSignalHandler(const QString & name){
    //qDebug()<< "signalHandler OK";
    m_signalHandler=name;
}


QVariant DbusService::dbus(){
    QDeclarativeContext * ctx = QDeclarativeEngine::contextForObject(this);
    return ctx->engine()->rootContext()->contextProperty(m_signalHandler);
}


void DbusService::checkServiceExists(){
    if(m_path.isNull()
           || m_service.isNull()
            || m_signalHandler.isNull()
            ){
        //qDebug()<< "pas de publication de l objet dans le contexte";
        return;
    }

    qDebug()<< "registration object";
    registerServ();
}


void DbusService::serviceOwnerChanged(QString name,QString oldOwner,QString newOwner){
    if(m_service == name){
         qDebug()<< "serviceOwnerChanged " << name << oldOwner << newOwner;
         if(!newOwner.isEmpty()){
             if(init)
                 return;//déjà initialisé, faut il le refaire ?

             qDebug()<< "dbus service created";
             registerServ();
         }else{
             qDebug()<< "dbus uninitialised";
             emit(uninitialized());
         }
    }
}


void DbusService::registerServ(){
    serv = new QDBusInterface(m_service,m_path,QString(), QDBusConnection::sessionBus(),this);
    if(!serv->isValid()){
        qDebug()<< "service non encore present sur DBUS";
        serv=0;
        return;
    }
    QDeclarativeContext * ctx = QDeclarativeEngine::contextForObject(this);
    ctx->engine()->rootContext()->setContextProperty(m_signalHandler,serv);
    qDebug()<< "creation de l objet :"<<  m_signalHandler;
    qDebug()<< "IS valid: " << serv->isValid();
    init=true;
    qDebug()<< "dbus initialised";
    emit(initialized());
}



void DbusService::invokeDbusMethod(QString methodName,QList<QVariant> argumentList){
    if(!isConnected()){
         qDebug()<<"Service Not Availlable!!!";
        return;
    }
    QDBusPendingReply<> replay = serv->asyncCallWithArgumentList(methodName, argumentList);
    replay.waitForFinished();
    if(replay.isError()){
        qDebug()<<"error while call:"<<replay.error();
    }
    //return replay.value();
}

bool DbusService::isConnected(){
    if(serv==0)
        return false;
    return serv->isValid();
}




































/*void DbusService::registerSignal(QString dbusSgl,QString qmlSgl){
    const char * dbuscc = dbusSgl.toUtf8();
    const char * qmlcc = qmlSgl.toUtf8();

    bool ok1 = QObject::connect(serv,dbuscc,this,qmlcc);
    qDebug()<< "register signal dur "<<ok1;
}*/


/*QDBusReply<bool> reply = QDBusConnection::sessionBus().interface()->isServiceRegistered(m_service);
if (!reply.isValid()){
    qDebug()<< "erreur lors de l accès au deamon DBUS";
    return;
}
if(!reply.value()){
    qDebug()<< "le service nexiste pas encore pour le deamon DBUS";
    return;
}*/

/*if(!m_signalHandler.isNull()){
    engine->rootContext()->setContextProperty(m_signalHandler, serv);
}*/
//
//qDebug()<< "dbus OK" ;

//QDBusAbstractInterface *abstractServ = serv;

/*bool ok1 = QObject::connect(serv,"2started(int)",this,"2started(int)");
qDebug()<< "register signal dur "<<ok1;

ok1 = QObject::connect(serv,"2positionChanged(QString)",this,"2positionChanged(QString)");
qDebug()<< "register signal dur "<<ok1;*/




/*bool ok1 = QObject::connect(serv,"2keyEvent(int,QString)",this,"2keyEvent(int,QString)");
qDebug()<< "connextion dur "<<ok1;

ok1 = QObject::connect(serv,"2started(int)",this,"2started(int)");
qDebug()<< "connextion dur "<<ok1;
*/



/* iterate trough serv's methods =====> tout se passe coe si il fallait activer klk chose*/
/*
const QMetaObject *senderMeta = serv->metaObject();
const QMetaObject *receverMeta = this->metaObject();

for(int i = 2; i < receverMeta->methodCount(); i++) {
    const QMetaMethod receverMethod = receverMeta->method(i);
    QString signet = receverMeta->normalizedSignature(receverMethod.signature());
    if(receverMethod.methodType() == QMetaMethod::Signal) {
        const int receverSignalIndex =  receverMethod.methodIndex();
        QString signatureRec = receverMethod.signature();

        const int senderSignalIndex =  senderMeta->indexOfMethod(receverMethod.signature());
        if(senderSignalIndex == -1){
            qDebug()<< "signal "<<signet<<" non trouvé sur DBUS";
            continue;
        }

        //moche mais marche
        QString qSgl = "2";
        qSgl.append(signet);
        const char * sgl1 = qSgl.toAscii();
        const char * sgl2 = qSgl.toAscii();


        bool ok1 = QObject::connect(serv,sgl1,this,sgl2);

        qDebug()<< "connextion auto --"<<receverMethod.signature()<<"--"<<ok1;
        //QObject::connect(serv,SIGNAL(started(int)),this,SIGNAL("started(int)"));
        // ne marche pas mais plus propre et il manque rien pr que ça marche
        //bool ok1 = QMetaObject::connect(serv,senderSignalIndex,this,receverSignalIndex);
        //qDebug()<< "connextion pour--"<<receverMethod.signature()<<"--"<<ok1;

    }
}
*/
